package com.oldking.controller;

import com.oldking.domain.AudioInfo;
import com.oldking.domain.VideoData;
import com.oldking.domain.VideoInfo;
import com.oldking.domain.VideoTask;
import com.oldking.utils.*;
import javafx.beans.InvalidationListener;
import javafx.beans.Observable;
import javafx.beans.value.ChangeListener;
import javafx.beans.value.ObservableValue;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.event.ActionEvent;
import javafx.event.EventHandler;
import javafx.fxml.FXML;
import javafx.fxml.Initializable;
import javafx.scene.Cursor;
import javafx.scene.Node;
import javafx.scene.control.*;
import javafx.scene.control.cell.PropertyValueFactory;
import javafx.scene.control.cell.TextFieldTableCell;
import javafx.scene.input.MouseEvent;
import javafx.scene.layout.GridPane;
import javafx.scene.layout.HBox;
import javafx.scene.layout.Pane;
import javafx.scene.media.Media;
import javafx.scene.media.MediaPlayer;
import javafx.scene.media.MediaView;
import javafx.scene.paint.Color;
import javafx.scene.paint.Paint;
import javafx.scene.shape.LineTo;
import javafx.scene.shape.MoveTo;
import javafx.scene.shape.Path;
import javafx.scene.shape.Rectangle;
import javafx.scene.text.Font;
import javafx.scene.text.Text;
import javafx.scene.text.TextFlow;
import javafx.stage.FileChooser;
import javafx.util.Duration;
import org.jaudiotagger.audio.exceptions.CannotReadException;
import org.jaudiotagger.audio.exceptions.InvalidAudioFrameException;
import org.jaudiotagger.audio.exceptions.ReadOnlyFileException;
import org.jaudiotagger.audio.mp3.MP3AudioHeader;
import org.jaudiotagger.audio.mp3.MP3File;
import org.jaudiotagger.tag.TagException;
import org.springframework.stereotype.Component;
import org.springframework.util.ObjectUtils;
import start.StarterClass;

import java.io.*;
import java.net.URL;
import java.util.List;
import java.util.ResourceBundle;

@Component
public class AddAudioController implements Initializable {

    private static String durationTime = VideoData.getVideoInfoByKey(VideoData.getKey()).getDuration();

    private MediaPlayer mediaPlayer;
    private StarterClass application;

    @FXML
    private MediaView mediaAudioView;
    @FXML
    private GridPane gridPaneId;
    @FXML
    private TableView videoManageView;
    @FXML
    private Slider volSlider;
    @FXML
    private Slider minSlider;
    @FXML
    private TextFlow currentTime;
    @FXML
    private TextFlow totalTime;
    @FXML
    private TableView audioView;

    @FXML
    private TableColumn audioTaskNameColumn;
    @FXML
    private TableColumn audioSpdColumn;
    @FXML
    private TableColumn audioPitColumn;
    @FXML
    private TableColumn audioVolColumn;
    @FXML
    private TableColumn audioSizeColumn;
    @FXML
    private TableColumn audioPerColumn;
    @FXML
    private TableColumn pathColumn;
    @FXML
    private TableColumn audioOpration;
    @FXML
    private Pane sliderPane;

    @FXML
    private ChoiceBox audioSpd;
    @FXML
    private ChoiceBox audioPit;
    @FXML
    private ChoiceBox audioVol;
    @FXML
    private ChoiceBox audioPer;
    @FXML
    private TextArea audioTextAreaId;

    @FXML
    private void back_videotask(ActionEvent event) {
        mediaPlayer.stop();
        application.gotoeditvideo("item");
    }

    @FXML
    private void openvidFile(ActionEvent event) {
        FileChooser fileChooser = new FileChooser();
        FileChooser.ExtensionFilter filter = new FileChooser.ExtensionFilter("Select a File (*.mp4)", "*.mp4");
        fileChooser.getExtensionFilters().add(filter);
        File file = fileChooser.showOpenDialog(null);

    }

    public void setApp(StarterClass application) {
        this.application = application;
    }

    @Override
    public void initialize(URL url, ResourceBundle rb) {
        audioSpd.getItems().addAll("0","1","2", "3", "4", "5", "6", "7", "8");
        //设置选中
        audioSpd.getSelectionModel().select("5");
        audioPit.getItems().addAll("0","1","2", "3", "4", "5", "6", "7", "8");
        //设置选中
        audioPit.getSelectionModel().select("5");
        audioVol.getItems().addAll("0","1","2", "3", "4", "5", "6", "7", "8","9", "10", "11", "12");
        //设置选中
        audioVol.getSelectionModel().select("5");
//        audioPer.getItems().addAll("chinese_xiaoqi_common", "chinese_xiaoyu_common", "chinese_xiaowen_common", "chinese_huaxiaogang_common", "chinese_huaxiaowei_common", "chinese_huaxiaoxuan_common");
//        //设置选中
//        audioPer.getSelectionModel().select("chinese_xiaoyu_common");
        // 精品库
//        audioPer.getItems().addAll("5003", "5118", "106", "110", "111", "103");
//        //设置选中
//        audioPer.getSelectionModel().select("5003");

        audioPer.getItems().addAll("3", "4", "5", "6", "7", "8", "110", "111", "5003", "5118", "106");
        //设置选中
        audioPer.getSelectionModel().select("5003");
        audioTextAreaId.setWrapText(true);

    }

    private void showAllRectlage(Slider minSlider) {
        ObservableList<VideoTask> taskList = FXCollections.observableArrayList();
        List<VideoInfo> videoInfoList = VideoData.getVideoInfoList();
        for (VideoInfo videoInfo : videoInfoList) {
            List<VideoTask> videotask = videoInfo.getVideotask();
            taskList.addAll(videotask);
        }
        for (int i = 0; i < taskList.size(); i++) {
            VideoTask videoTask = taskList.get(i);
            int intStart = CommonTimeUtil.Stringtime2Second(videoTask.getStartTime().getText());
            int intEnd = CommonTimeUtil.Stringtime2Second(videoTask.getEndTime().getText());
            int t = CommonTimeUtil.Stringtime2Second(durationTime);
            double vStart = (intStart * this.minSlider.getPrefWidth() / t);
            double vEnd = (intEnd * this.minSlider.getPrefWidth() / t);
            String id = String.valueOf(i + 1);
            addOneSliderRectangle(sliderPane, "startTimeBtn", id, vStart);
            addOneSliderRectangle(sliderPane, "endTimeBtn", id, vEnd);
        }
    }


    private void addOneSliderRectangle(Pane sliderPane, String btnTypleText, String id, double v) {

        Rectangle rectangleStart = createSliderNewRectangle(CommonColorUtil.getColorByKey(Integer.valueOf(id)), v, btnTypleText + id, id);
        ObservableList<Node> children = sliderPane.getChildren();
        if (children.size() == 1) {
            sliderPane.getChildren().add(rectangleStart);
            return;
        }
        boolean flag = false;
        for (int i = 1; i < children.size(); i++) {
            if (ObjectUtils.isEmpty(children.get(i).getId())) {
                continue;
            }
            if (children.get(i).getId().contains(btnTypleText + id)) {
                flag = true;
                break;
            }
        }
        if (flag) {
            for (int i = 1; i < children.size(); i++) {
                if (ObjectUtils.isEmpty(children.get(i).getId())) {
                    continue;
                }
                Rectangle r = (Rectangle) children.get(i);

                if (r.getId().equals(btnTypleText + id)) {
                    sliderPane.getChildren().set(i, rectangleStart);
                    return;
                }
            }
        } else {
            sliderPane.getChildren().add(rectangleStart);
        }
    }

    private void addSliderMouseDragged(Text current) {
        minSlider.setOnMouseDragged(new EventHandler<MouseEvent>() {
            @Override
            public void handle(MouseEvent event) {
                long l = Math.round(minSlider.getValue());
                try {
                    mediaPlayer.seek(Duration.seconds(minSlider.getValue()));
                    VideoData.setCurrentTime((int) minSlider.getValue());
                    setCurrentByTime(l, current);
                } catch (Exception e) {

                }
            }
        });
    }


    private void setCurrentByTime(long l, Text current) {
        current.setFont(new Font(15));
        current.setText(CommonTimeUtil.secondToTime(l));
        if (currentTime.getChildren().size() == 0) {
            currentTime.getChildren().add(current);
        } else {
            currentTime.getChildren().set(0, current);
        }
    }

    @FXML
    private void playVid(ActionEvent event) {
        mediaPlayer.play();
        mediaPlayer.setRate(1);
    }

    @FXML
    private void pauseVid(ActionEvent event) {
        mediaPlayer.pause();
    }

    @FXML
    private void stopVid(ActionEvent event) {
        mediaPlayer.stop();
    }

    @FXML
    private void exitProg(ActionEvent event) {
        System.exit(0);
    }


    public void createmp3(ActionEvent actionEvent) {
        if (ObjectUtils.isEmpty(audioTextAreaId.getText())) {
            AlertMessageUtil.msg(Alert.AlertType.ERROR, "waring", "请输入要转换的文字", "");
            return;
        }
        String audioTextAreav = audioTextAreaId.getText();
        String audioSpdv = audioSpd.getValue().toString();
        String audioPitv = audioPit.getValue().toString();
        String audioVolv = audioVol.getValue().toString();
        String audioPerv = audioPer.getValue().toString();
        VideoInfo videoInfo = VideoData.getVideoInfoByKey(VideoData.getKey());
        String audioFilePath = videoInfo.getPath().substring(0, videoInfo.getPath().lastIndexOf("."));
        String fileName = videoInfo.getFileName().substring(0, videoInfo.getFileName().lastIndexOf("."));

        File file = new File(audioFilePath);
        if (!file.exists()) {
            file.mkdirs();
        }

        AudioInfo audioInfo = new AudioInfo();
        audioInfo.setId(UUIDUtil.getUUID());
        audioInfo.setAudioPerColumn(audioPerv);
        audioInfo.setAudioPitColumn(audioPitv);
        audioInfo.setAudioSpdColumn(audioSpdv);
        audioInfo.setAudioVolColumn(audioVolv);
        audioInfo.setAudioTaskNameColumn(fileName + "_" + audioInfo.getId());
        audioInfo.setPathColumn(audioFilePath + "/" + fileName + "_" + audioInfo.getId() + ".mp3");

        HBox hBox = new HBox();
        Button auditionBtn = new Button("试听");
        auditionBtn.setId(String.valueOf(audioView.getItems().size() + 1));
        hBox.getChildren().addAll(auditionBtn);

        auditionBtn.setOnMouseClicked(ActionEvent -> {
            String id = ((Node) ActionEvent.getSource()).getId();
            ObservableList<AudioInfo> audioTaskList = audioView.getItems();
            for (int i = 0; i < audioTaskList.size(); i++) {
                if (id.equals(String.valueOf(i + 1))) {
                    playMp3(audioTaskList.get(i).getPathColumn());
                    return;
                }
            }

        });

        String mp3lastPath = audioFilePath + "/" + fileName + "_" + audioInfo.getId() + ".mp3";
        String srtlastPath = audioFilePath + "/" + fileName + "_" + audioInfo.getId() + ".srt";
        // 百度 生成mp3
        VoiceComposeUtil.getMP3ByText(mp3lastPath, audioTextAreav, audioSpdv, audioPitv, audioVolv, audioPerv);
        // 华为 生成mp3
        //  VoiceComposeUtil.ttsCustom(Integer.valueOf(audioPitv),Integer.valueOf(audioSpdv) ,Integer.valueOf(audioVolv) ,audioTextAreav,audioPerv,mp3lastPath);
        int mp3Len = getMP3Length(mp3lastPath);
        audioInfo.setAudioSizeColumn(CommonTimeUtil.secondToTime((long)mp3Len));
        audioInfo.setAudioOpration(hBox);
        VideoData.getAudioInfoList().add(audioInfo);
        ObservableList<AudioInfo> audioList = audioView.getItems();
        audioList.add(audioInfo);
        audioView.setItems(audioList);
        initTableColumn();
        // 生成字幕文件
        getSrtByText(srtlastPath, audioTextAreav,mp3Len);
        AlertMessageUtil.msg(Alert.AlertType.INFORMATION, "INFORMATION", "生成音频完成", "");
    }

    private int getSrtByText(String srtlastPath, String audioTextAreav, int mp3Len) {
        checkFileExist(srtlastPath);
        audioTextAreav = audioTextAreav.replaceAll("。", ".");
        String[] splitText = audioTextAreav.split("\\.");
        FileOutputStream fos = null;
        try {
            fos = new FileOutputStream(new File(srtlastPath));
            OutputStreamWriter osw = new OutputStreamWriter(fos, "UTF-8");
            BufferedWriter bw = new BufferedWriter(osw);

            for (int i = 0; i < splitText.length; i++) {
                bw.write(i + 1 + "\t\n");
                String timeStr = getTimeByLength(audioTextAreav, mp3Len, i, splitText);
                bw.write(timeStr + "\t\n");
                bw.write(splitText[i] + ".\t\n");
            }
            bw.close();
            osw.close();
            fos.close();
            return mp3Len;
        } catch (IOException e) {
            e.printStackTrace();
        }
        return 0;
    }

    private String getTimeByLength(String audioTextAreav, int mp3Len, int j, String[] splitText) {
        float passTime = 0f;
        for (int i = 0; i < j; i++) {
            passTime += splitText[i].length();
        }
        // 已经播放的总时长
        float currentStart = passTime * mp3Len / (float) audioTextAreav.length();
        // 当前行的播放时间
        float sec = splitText[j].length() * mp3Len / (float) audioTextAreav.length();
        float currentEnd = currentStart + sec;
        String start = CommonTimeUtil.secondToTime((long) currentStart);
        String end = CommonTimeUtil.secondToTime((long) currentEnd);
        //00:00:01,0 --> 00:00:10,540
        return start + ",0 --> " + end + ",0";
    }

    private int getMP3Length(String mp3Path) {
        try {
            MP3File file = new MP3File(mp3Path);
            MP3AudioHeader audioHeader = (MP3AudioHeader) file.getAudioHeader();
            return audioHeader.getTrackLength();
        } catch (IOException e) {
            e.printStackTrace();
        } catch (TagException e) {
            e.printStackTrace();
        } catch (ReadOnlyFileException e) {
            e.printStackTrace();
        } catch (InvalidAudioFrameException e) {
            e.printStackTrace();
        }
        return 0;
    }

    private void checkFileExist(String srtPath) {
        File srtFile = new File(srtPath);
        if (srtFile.exists()) {
            srtFile.delete();
        } else {
            try {
                srtFile.createNewFile();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }


    private void playMp3(String pathColumn) {
        Thread thread = new Thread() {
            public void run() {
                VoiceComposeUtil.playMP3(pathColumn);
            }
        };
        thread.start();

    }


    private Rectangle createSliderNewRectangle(String color, double X, String nodeId, String id) {
        Rectangle rectangle = new Rectangle();
        rectangle.setId(nodeId);
        rectangle.setFill(Paint.valueOf(color));
        rectangle.setX(X);
        rectangle.setWidth(2.0);
        rectangle.setHeight(23.0);
        return rectangle;
    }

    private void initTableColumn() {
        audioTaskNameColumn.setCellValueFactory(new PropertyValueFactory("audioTaskNameColumn"));
        audioSpdColumn.setCellValueFactory(new PropertyValueFactory("audioSpdColumn"));
        audioPitColumn.setCellValueFactory(new PropertyValueFactory("audioPitColumn"));
        audioVolColumn.setCellValueFactory(new PropertyValueFactory("audioVolColumn"));
        audioPerColumn.setCellValueFactory(new PropertyValueFactory("audioPerColumn"));
        pathColumn.setCellValueFactory(new PropertyValueFactory("pathColumn"));
        audioOpration.setCellValueFactory(new PropertyValueFactory("audioOpration"));
        audioSizeColumn.setCellValueFactory(new PropertyValueFactory("audioSizeColumn"));
    }


    public void submitVideoTask(ActionEvent actionEvent) {
    }

    public void addAudio(ActionEvent actionEvent) {
    }

    public void delAudio(ActionEvent actionEvent) {
    }

    public void pushOut(ActionEvent actionEvent) {
        application.gotoaudiomanage("");
    }
}